package org.flexharmony.eclipse.properties.classinclusion;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.flexharmony.eclipse.HarmonyPlugin;
import org.flexharmony.eclipse.domain.ExclusionFilter;
import org.flexharmony.eclipse.domain.IncludedSourceFolder;
import org.flexharmony.eclipse.domain.InclusionFilter;


public class InclusionExclusionDialog extends Wizard
{
  private IncludedSourceFolder folder;
  
  private IProject project;
  
  private IFolder sourceFolder;
  
  private InclusionExclusionPanel patternPanel;
  
  public InclusionExclusionDialog(IncludedSourceFolder folder, IProject project)
  {
    this.folder = folder;
    this.project = project;
    setWindowTitle("FlexHarmony Inclusion and Exclusion Patterns");
    
    sourceFolder = project.getFolder(folder.folderPath);
  }

  @Override
  public void addPages()
  {
    patternPanel = new InclusionExclusionPanel();
    addPage(patternPanel);
  }

  @Override
  public boolean performFinish()
  {
    List<String> includedPatterns = new ArrayList<String>();
    TableItem[] includedItems = patternPanel.inclusionTable.getItems();
    for (TableItem includedItem : includedItems)
    {
      includedPatterns.add((String)includedItem.getData());
    }
    
    InclusionFilter includedFilter = folder.getIncludedFilter();
    includedFilter.patterns.clear();
    includedFilter.patterns.addAll(includedPatterns);

    List<String> excludedPatterns = new ArrayList<String>();
    TableItem[] excludedItems = patternPanel.exclusionTable.getItems();
    for (TableItem excludedItem : excludedItems)
    {
      excludedPatterns.add((String)excludedItem.getData());
    }
    
    ExclusionFilter excludedFilter = folder.getExcludedFilter();
    excludedFilter.patterns.clear();
    excludedFilter.patterns.addAll(excludedPatterns);

    return true;
  }
  
  private class InclusionExclusionPanel extends WizardPage implements SelectionListener
  {
    private Table inclusionTable;
    private Button inclAddBtn;
    private Button inclAddMultBtn;
    private Button inclEditBtn;
    private Button inclRemoveBtn;
    
    private Table exclusionTable;
    private Button exclAddBtn;
    private Button exclAddMultBtn;
    private Button exclEditBtn;
    private Button exclRemoveBtn;
    
    public InclusionExclusionPanel()
    {
      super("inclusionexclusion");
      setTitle("FlexHarmony Inclusion and Exclusion Patterns");
      setDescription("Add or remove inclusion and exclusion patterns for Java source files that will be converted to ActionScript");
    }

    public void widgetDefaultSelected(SelectionEvent evt)
    {
    }

    public void widgetSelected(SelectionEvent evt)
    {
      if (evt.getSource() == inclusionTable)
      {
        boolean hasSelection = inclusionTable.getSelectionCount() > 0;
        inclEditBtn.setEnabled(hasSelection);
        inclRemoveBtn.setEnabled(hasSelection);
      }
      else if (evt.getSource() == exclusionTable)
      {
        boolean hasSelection = exclusionTable.getSelectionCount() > 0;
        exclEditBtn.setEnabled(hasSelection);
        exclRemoveBtn.setEnabled(hasSelection);
      }
    }

    public void createControl(Composite parent)
    {
      Composite dialogPanel = new Composite(parent, SWT.NONE);
      GridLayout compositeLayout = new GridLayout();
      compositeLayout.numColumns = 2;
      compositeLayout.marginLeft = 5;
      dialogPanel.setLayout(compositeLayout);

      Composite inclusionPanel = new Composite(dialogPanel, SWT.NONE);
      GridData gd = new GridData(GridData.FILL_BOTH);
      gd.horizontalSpan = 2;
      inclusionPanel.setLayoutData(gd);
      
      GridLayout tablePanelLayout = new GridLayout();
      tablePanelLayout.marginHeight = 0;
      tablePanelLayout.marginWidth = 0;
      tablePanelLayout.numColumns = 2;
      tablePanelLayout.verticalSpacing = 0;
      inclusionPanel.setLayout(tablePanelLayout);

      Label label = new Label(inclusionPanel, SWT.NONE);
      gd = new GridData();
      gd.horizontalSpan = 2;
      gd.horizontalIndent = 5;
      label.setLayoutData(gd);
      label.setText("Inclusion patterns:");
      
      GridData tableData = new GridData();
      tableData.grabExcessVerticalSpace = true;
      tableData.grabExcessHorizontalSpace = true;
      tableData.verticalAlignment = GridData.FILL;
      tableData.horizontalAlignment = GridData.FILL;
      tableData.verticalIndent = 7;

      inclusionTable = new Table(inclusionPanel, SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE);
      inclusionTable.addSelectionListener(this);
      inclusionTable.setHeaderVisible(false);
      inclusionTable.setLayoutData(tableData);
      inclusionTable.setLinesVisible(false);

      TableColumn tableColumn1 = new TableColumn(inclusionTable, SWT.NONE);
      tableColumn1.setWidth(250);
      tableColumn1.setText("Patterns");

      List<String> initIncludePatterns = folder.getIncludedFilter().patterns;
      Image includeFilterImage = HarmonyPlugin.getImage("icons/inclusionFilter.gif");
      for (String initIncludePattern : initIncludePatterns)
      {
        TableItem ti = new TableItem(inclusionTable, SWT.NONE);
        ti.setData(initIncludePattern);
        ti.setText(initIncludePattern);
        ti.setImage(includeFilterImage);
      }

      GridLayout buttonPanelLayout = new GridLayout();
      buttonPanelLayout.numColumns = 1;

      Canvas buttonPanel = new Canvas(inclusionPanel, SWT.NONE);
      buttonPanel.setLayout(buttonPanelLayout);
      GridData buttonPanelData = new GridData();
      buttonPanelData.verticalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
      buttonPanel.setLayoutData(buttonPanelData);

      GridData buttonData = new GridData();
      buttonData.verticalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
      buttonData.widthHint = 150;
      inclAddBtn = new Button(buttonPanel, SWT.NONE);
      inclAddBtn.setText("Add...");
      inclAddBtn.setLayoutData(buttonData);
      inclAddBtn.addSelectionListener(new SelectionAdapter()
      {
        public void widgetSelected(SelectionEvent sevt)
        {
          includeAdd();
        }
      });

      inclAddMultBtn = new Button(buttonPanel, SWT.NONE);
      inclAddMultBtn.setText("Add Multiple...");
      inclAddMultBtn.setLayoutData(buttonData);
      inclAddMultBtn.addSelectionListener(new SelectionAdapter()
      {
        public void widgetSelected(SelectionEvent sevt)
        {
          includeAddMultiple();
        }
      });

      inclEditBtn = new Button(buttonPanel, SWT.NONE);
      inclEditBtn.setText("Edit...");
      inclEditBtn.setLayoutData(buttonData);
      inclEditBtn.setEnabled(false);
      inclEditBtn.addSelectionListener(new SelectionAdapter()
      {
        public void widgetSelected(SelectionEvent sevt)
        {
          includeEdit();
        }
      });

      inclRemoveBtn = new Button(buttonPanel, SWT.NONE);
      inclRemoveBtn.setText("Remove...");
      inclRemoveBtn.setLayoutData(buttonData);
      inclRemoveBtn.setEnabled(false);
      inclRemoveBtn.addSelectionListener(new SelectionAdapter()
      {
        public void widgetSelected(SelectionEvent sevt)
        {
          includeRemove();
        }
      });

      
      Composite exclusionPanel = new Composite(dialogPanel, SWT.NONE);
      gd = new GridData(GridData.FILL_BOTH);
      gd.horizontalSpan = 2;
      exclusionPanel.setLayoutData(gd);
      
      tablePanelLayout = new GridLayout();
      tablePanelLayout.marginHeight = 0;
      tablePanelLayout.marginWidth = 0;
      tablePanelLayout.numColumns = 2;
      tablePanelLayout.verticalSpacing = 0;
      exclusionPanel.setLayout(tablePanelLayout);

      label = new Label(exclusionPanel, SWT.NONE);
      gd = new GridData();
      gd.horizontalSpan = 2;
      gd.horizontalIndent = 5;
      label.setLayoutData(gd);
      label.setText("Exclusion patterns:");
      
      tableData = new GridData();
      tableData.grabExcessVerticalSpace = true;
      tableData.grabExcessHorizontalSpace = true;
      tableData.verticalAlignment = GridData.FILL;
      tableData.horizontalAlignment = GridData.FILL;
      tableData.verticalIndent = 7;

      exclusionTable = new Table(exclusionPanel, SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE);
      exclusionTable.addSelectionListener(this);
      exclusionTable.setHeaderVisible(false);
      exclusionTable.setLayoutData(tableData);
      exclusionTable.setLinesVisible(false);

      tableColumn1 = new TableColumn(exclusionTable, SWT.NONE);
      tableColumn1.setWidth(250);
      tableColumn1.setText("Patterns");
      
      List<String> initExcludePatterns = folder.getExcludedFilter().patterns;
      Image excludeFilterImage = HarmonyPlugin.getImage("icons/exclusionFilter.gif");
      for (String initExcludePattern : initExcludePatterns)
      {
        TableItem ti = new TableItem(exclusionTable, SWT.NONE);
        ti.setData(initExcludePattern);
        ti.setText(initExcludePattern);
        ti.setImage(excludeFilterImage);
      }

      buttonPanelLayout = new GridLayout(); 
      buttonPanelLayout.numColumns = 1;

      buttonPanel = new Canvas(exclusionPanel, SWT.NONE);
      buttonPanel.setLayout(buttonPanelLayout);
      buttonPanelData = new GridData();
      buttonPanelData.verticalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
      buttonPanel.setLayoutData(buttonPanelData);

      buttonData = new GridData();
      buttonData.verticalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
      buttonData.widthHint = 150;
      exclAddBtn = new Button(buttonPanel, SWT.NONE);
      exclAddBtn.setText("Add...");
      exclAddBtn.setLayoutData(buttonData);
      exclAddBtn.addSelectionListener(new SelectionAdapter()
      {
        public void widgetSelected(SelectionEvent sevt)
        {
          excludeAdd();
        }
      });

      exclAddMultBtn = new Button(buttonPanel, SWT.NONE);
      exclAddMultBtn.setText("Add Multiple...");
      exclAddMultBtn.setLayoutData(buttonData);
      exclAddMultBtn.addSelectionListener(new SelectionAdapter()
      {
        public void widgetSelected(SelectionEvent sevt)
        {
          excludeAddMultiple();
        }
      });

      exclEditBtn = new Button(buttonPanel, SWT.NONE);
      exclEditBtn.setText("Edit...");
      exclEditBtn.setLayoutData(buttonData);
      exclEditBtn.setEnabled(false);
      exclEditBtn.addSelectionListener(new SelectionAdapter()
      {
        public void widgetSelected(SelectionEvent sevt)
        {
          excludeEdit();
        }
      });

      exclRemoveBtn = new Button(buttonPanel, SWT.NONE);
      exclRemoveBtn.setText("Remove...");
      exclRemoveBtn.setLayoutData(buttonData);
      exclRemoveBtn.setEnabled(false);
      exclRemoveBtn.addSelectionListener(new SelectionAdapter()
      {
        public void widgetSelected(SelectionEvent sevt)
        {
          excludeRemove();
        }
      });
      
      setControl(dialogPanel);
    }
    
    private void includeAdd()
    {
      String pattern = showAddDialog(true, null);
      if (pattern != null)
      {
        TableItem ti = new TableItem(inclusionTable, SWT.NONE);
        ti.setData(pattern);
        ti.setText(pattern);
        ti.setImage(HarmonyPlugin.getImage("icons/inclusionFilter.gif"));
      }
    }
    
    private void includeAddMultiple()
    {
      List<String> patterns = showSourceDialog(true, true);
      if (patterns != null)
      {
        Image image = HarmonyPlugin.getImage("icons/inclusionFilter.gif");
        for (String pattern : patterns)
        {
          TableItem ti = new TableItem(inclusionTable, SWT.NONE);
          ti.setData(pattern);
          ti.setText(pattern);
          ti.setImage(image);
        }
      }
    }
    
    private void includeEdit()
    {
      TableItem[] selectedItems = inclusionTable.getSelection();
      if (selectedItems.length > 0)
      {
        TableItem selectedItem = selectedItems[0];
        String pattern = (String)selectedItem.getData();
        
        String newPattern = showAddDialog(true, pattern);
        if (newPattern != null)
        {
          selectedItem.setData(newPattern);
          selectedItem.setText(newPattern);
        }
      }
    }
    
    private void includeRemove()
    {
      inclusionTable.remove(inclusionTable.getSelectionIndices());
    }

    private void excludeAdd()
    {
      String pattern = showAddDialog(false, null);
      if (pattern != null)
      {
        TableItem ti = new TableItem(exclusionTable, SWT.NONE);
        ti.setData(pattern);
        ti.setText(pattern);
        ti.setImage(HarmonyPlugin.getImage("icons/exclusionFilter.gif"));
      }
    }
    
    private void excludeAddMultiple()
    {
      List<String> patterns = showSourceDialog(true, false);
      if (patterns != null)
      {
        Image image = HarmonyPlugin.getImage("icons/exclusionFilter.gif");
        for (String pattern : patterns)
        {
          TableItem ti = new TableItem(exclusionTable, SWT.NONE);
          ti.setData(pattern);
          ti.setText(pattern);
          ti.setImage(image);
        }
      }
    }
    
    private void excludeEdit()
    {
      TableItem[] selectedItems = exclusionTable.getSelection();
      if (selectedItems.length > 0)
      {
        TableItem selectedItem = selectedItems[0];
        String pattern = (String)selectedItem.getData();
        
        String newPattern = showAddDialog(false, pattern);
        if (newPattern != null)
        {
          selectedItem.setData(newPattern);
          selectedItem.setText(newPattern);
        }
      }
    }
    
    private void excludeRemove()
    {
      exclusionTable.remove(exclusionTable.getSelectionIndices());
    }
    
    private String showAddDialog(boolean include, String initPattern)
    {
      Shell shell = HarmonyPlugin.getInstance().getWorkbench().getDisplay().getActiveShell();
      AddSinglePatternDialog addDialog = new AddSinglePatternDialog(shell, initPattern, sourceFolder, include);
      addDialog.create();
      addDialog.open();
      if (addDialog.isAdd())
      {
        return addDialog.getPattern();      
      }
      else
      {
        return null;
      }
    }
    
    private List<String> showSourceDialog(boolean multiMode, boolean include)
    {
      Shell shell = HarmonyPlugin.getInstance().getWorkbench().getDisplay().getActiveShell();
      SelectJavaSourceDialog sourceDialog = new SelectJavaSourceDialog(shell, sourceFolder, multiMode, include);
      sourceDialog.create();
      sourceDialog.open();
      
      if (sourceDialog.isAdd())
      {
        List<IResource> selectedResources = sourceDialog.getSelectedResources();
        List<String> patterns = new ArrayList<String>();
        
        for (IResource resource : selectedResources)
        {
          IPath path = resource.getFullPath();
          path = path.removeFirstSegments(path.matchingFirstSegments(sourceFolder.getFullPath()));
          if (resource instanceof IFolder)
          {
            patterns.add(path.toString() + "/.*");
          }
          else if (resource instanceof IFile)
          {
            patterns.add(path.toString());
          }
        }
        
        return patterns;
      }
      else
      {
        return null;
      }
    }
  }

}
